package yunjiao.javatutorials.guava.concurrent;

import com.google.common.util.concurrent.AbstractScheduledService;
import com.google.common.util.concurrent.MoreExecutors;
import lombok.extern.slf4j.Slf4j;

import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

/**
 * 异常任务无法恢复
 *
 * @author yangyunjiao
 */
@Slf4j
public class ExceptionSchedulerService extends AbstractScheduledService {
    @Override
    protected void runOneIteration() throws Exception {
        log.info("开机执行任务");
        throw new RuntimeException("异常：" + System.currentTimeMillis());
    }

    @Override
    protected Scheduler scheduler() {
        return Scheduler.newFixedRateSchedule(1, 1, TimeUnit.SECONDS);
    }


    public static void main(String[] args) throws InterruptedException, TimeoutException {
        ExceptionSchedulerService service = new ExceptionSchedulerService();

        // 添加状态监听
        service.addListener(new Listener() {
            @Override
            public void starting() {
                log.info("服务正在启动...");
            }

            @Override
            public void running() {
                log.info("服务已运行...");
            }

            @Override
            public void stopping(State from) {
                log.info("服务正在停止（原状态：" + from + "）...");
            }

            @Override
            public void terminated(State from) {
                log.info("服务已终止（原状态：" + from + "）...");
            }

            @Override
            public void failed(State from, Throwable failure) {
                log.info("服务失败（原状态：" + from + "）：" + failure.getMessage());
            }
        }, MoreExecutors.directExecutor());

        // 启动服务（异步）
        service.startAsync();
        service.awaitRunning(); // 阻塞等待服务启动成功（进入 RUNNING 状态）
        System.out.println("服务已启动，状态：" + service.state());

        // 运行5秒后停止服务
        TimeUnit.SECONDS.sleep(3);
        service.stopAsync(); // 异步停止
        service.awaitTerminated(3, TimeUnit.SECONDS); // 阻塞等待停止完成（最多等3秒）
        System.out.println("服务已停止，状态：" + service.state());
    }
}
